<?php

namespace pmvc\ioc;

/**
 * ObjectFactory
 *
 */
interface ObjectFactory {

	/**
	 * Returns objects of the given type from the factory.
	 * @param string $type the type name
	 * @return array
	 */
	function getObjectsOfType($type);

	/**
	 * Gets an object from the factory by it's id.
	 * @param string $id the objects id
	 * @return mixed|null
	 */
	function getObjectById($id);

	/**
	 * Gets an object from the factory by it's name.
	 * @param string $name the objects name
	 * @return mixed|null
	 */
	function getObjectByName($name);

	/**
	 * Returns all of the object ids in this factory.
	 * @return array of object ids
	 */
	function getObjectIds();

	/**
	 * Returns all of the object names in this factory.
	 * @return array of object names
	 */
	function getObjectNames();

	/**
	 * Returns ids of objects of the given type in this factory.
	 * @param $type the object type
	 * @return array of ids
	 */
	function getObjectIdsOfType($type);

	/**
	 * Returns names of objects of the given type in this factory.
	 * @param $type the object type
	 * @return array of names
	 */
	function getObjectNamesOfType($type);

	/**
	 * Returns a boolean indicating whether or not the factory has
	 * an object with the given name optionally recursing to
	 * parent factories.
	 * @param string $name the name
	 * @param bool $recurse - whether or not to recurse
	 * @return bool
	 */
	function hasObjectWithName($name, $recurse=true);

	/**
	 * Returns a boolean indicating whether or not the factory has
	 * an object with the given id optionally recursing to
	 * parent factories.
	 * @param string $id the id
	 * @param bool $recurse - whether or not to recurse
	 * @return bool
	 */
	function hasObjectWithId($id, $recurse=true);

	/**
	 * Returns descriptors of the given type from the factory.
	 * @param string $type the type name
	 * @return array of ObjectDescriptor
	 */
	function getDescriptorsOfType($type);

	/**
	 * Gets a descriptor from the factory by it's id.
	 * @param string $id the descriptors id
	 * @return ObjectDescriptor|null
	 */
	function getDescriptorById($id);

	/**
	 * Gets a descriptor from the factory by it's name.
	 * @param string $name the descriptor name
	 * @return ObjectDescriptor|null
	 */
	function getDescriptorByName($name);
	
	/**
	 * Visits all {@link ObjectDescriptor}s in the {@link ObjectFactory}.
	 * Parameters passed to the visitor callback are:
	 * <ul>
	 * 	<li>{@code $descriptor} - the object descriptor</li>
	 * 	<li>{@code $get} - a callback that returns the instance of the object</li>
	 * </ul>
	 * If the visitor callback returns a boolean false value then the
	 * visitation is canceled early and no more objects are visited.
	 * Calling the {@code $get} is the equivelant of calling
	 * {@link ObjectFactory::getObjectById()}.
	 * @param callback $cb
	 */
	function visitDescriptors($cb);
	
	/**
	 * Adds an {@link ObjectDescriptor} to the factory and
	 * makes it available to the rest of the factory.
	 * @param ObjectDescriptor $desc
	 */
	function addObjectDescriptor(ObjectDescriptor $desc);
	
}

?>